package edu.sysu.demo.petstore.dog.issue;

import static edu.sysu.demo.petstore.dog.data.entity.Key.KeyType.RSA_PRIVATE;

import edu.sysu.demo.petstore.dog.key.KeyService;
import edu.sysu.demo.petstore.token.Issuer;
import java.security.PrivateKey;
import java.time.LocalDateTime;
import java.util.Optional;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Component
public class JwtIssueTokenService implements IssueTokenService {

  private static final int YEARS_TILL_EXPIRATION = 50;

  private final Issuer issuer;

  private final KeyService keyService;

  private volatile PrivateKey privateKey;

  @Autowired
  public JwtIssueTokenService(Issuer issuer, KeyService keyService) {
    this.issuer = issuer;
    this.keyService = keyService;
  }

  @Override
  public String issue(String subject) {

    return issuer.issueToken(
        subject,
        LocalDateTime.now().plusYears(YEARS_TILL_EXPIRATION),
        privateKey);
  }

  @PostConstruct
  @Transactional(readOnly = true)
  public synchronized void reload() {
    PrivateKey key = keyService.query("issue_key", RSA_PRIVATE);
    privateKey = Optional.ofNullable(key)
        .orElseThrow(() -> new IllegalStateException("Key DB not initialized"));
  }
}
